feat(cpp-boost-beast-server): add HTTP/1.1 server generator - #24783
feat(cpp-boost-beast-server): add HTTP/1.1 server generator#24783bold84 wants to merge 36 commits into
Conversation
…rver Move the direction-agnostic document pipeline, model lowering, parameter serialization facts, dialect policy, and schema-IR emission from CppBoostBeastClientCodegen into CppBoostBeastModelCodegen; extract CppBoostBeastOperationFacts from the client template assembler; add additionalEmbeddedTemplateDirs locator support and move shared model/validation templates to cpp-boost-beast-common. Client generated output is byte-identical; cppboostbeast suite (158 tests) green.
Add the cpp-boost-beast-server generator (BETA) emitting a C++17 Boost.Beast HTTP/1.1 server: strand-per-connection sessions with message_generator responses, encoded-segment routing with 404/405+Allow, OAS parameter deserialization (path simple/label/matrix, query form/space/pipe/deepObject, header simple, cookie form) with enum, pattern, and bound validation into RFC 9457 problem responses, JSON body codec over generated model to/fromJsonValue APIs, OR-of-AND security extraction with a deny-by-default Authorizer seam, single-shot strand posting responders, and an addApiImplStubs quick-start main. CMake links Boost 1.81+ json+url compiled libraries; -Wall/-W4 clean.
…e suites Add the server-regression OAS 3.1 fixture (path/query/header/cookie styles, enum/pattern/bound constraints, bearer + apiKey security), 12-test codegen suite (defaults, contract emission, stubs, IR stripping, multipart/x-www-form-urlencoded/text-*/event-stream/content-style/ cookie-matrix/ambiguous-route rejections, 3.0 compatibility), and the native loopback runtime test compiling and running the generated server against real sockets: 200/201/204 happy paths, 400 problem+json with errors[] for every constraint class, 404, 405+Allow, 413, 415, 401 with and without credentials, keep-alive, label-pattern paths, and pipe-delimited collections. Header params now look up lowercased field names; enum allow-lists render unescaped.
Add the deterministic cpp-boost-beast-server petstore sample (builds clean with -Wall and serves 501 stubs / 400 / 404 over HTTP/1.1), the generated generator documentation, and a three-OS sample build workflow covering Boost json+url consumers. API headers now emit the model namespace using-directive only when an API actually references a generated model class (map-only APIs such as store inventory compile standalone).
…erage Runtime: anonymous security alternatives (security: []) now bypass the authorization gate; 413 body-limit responses close the connection instead of re-reading leftover body bytes as a new request; responses mirror the request HTTP version and keep-alive preference; HttpServer::stop posts the acceptor close onto its strand; ResponderCore's completion flag is atomic and the handler-exception 500 routes through the guard; 401s carry WWW-Authenticate for http-scheme challenges; cookie names strip leading OWS; BodyJson handles uint64 numbers above INT64_MAX without throwing past the invalid_argument catch and supports any-type bodies; parseScalar enforces whole-input match and rejects inf/nan; problem JSON escapes bytes >= 0x7f to keep bodies valid UTF-8. Generator: request-body and parameter $refs are resolved before fact extraction so bodies and constraints survive; declared media-type parameters are normalized out of kMediaTypes; ranged status codes (2XX) and oauth2/openIdConnect/mutualTLS schemes are rejected at generation; integer/number/bool enums are validated at runtime like string enums; header and cookie params gain enum checks; route shape keys mirror the runtime splitter; dead x-server-route/kind/inner facts and the bodyKind helper are removed; shared OperationFacts gains the Apache header. Loopback coverage: anonymous-op bypass against a denying authorizer, integer-enum rejection/acceptance, and conventional spaced Cookie headers.
…tests
Generation gate:
- reject array/object cookie params, non-scalar array items, object
params other than query deepObject string maps, heterogeneous enums
- fix malformed security-scheme diagnostic quoting
Runtime:
- splitMatrixExploded(): strip repeated name= per element for
style=matrix explode=true path parameters
- router literal-over-parameter ranking (most literal segments wins,
ties keep registration order) so /pets/bulk beats /pets/{petId}
- re-arm the stream timer in send_response so deferred handler
completions are not aborted by an expired read deadline
- mirror request version/keep-alive on the 413 body_limit path
- deepObject required-missing now reports 400
- shared param-constraints partial: uniform pattern/length/bound
ladders across query, header, and cookie scalar parameters
- jsonEscape passes UTF-8 through; escapes only C0 controls and DEL
Rendering: minimum/maximum bounds emit long-double-safe literals
(plain integers gain .0), so int64 extremes compile under -Wall.
Tests: four new gate rejection tests plus a deepObject acceptance
test; runtime test hardened (compiler/Boost skip guards, file-based
output redirection, process-tree termination on timeout) and a new
validation-disabled end-to-end case; loopback driver covers matrix
explode, spaceDelimited, deepObject required, literal ranking,
deferred completions, WWW-Authenticate challenges, HTTP/1.0
mirroring incl. 413, cookie decoding, and duplicate-completion
guarding; locator precedence test now probes a template present in
both embedded dirs.
CI: Windows sample job installs boost-asio/beast/multiprecision
ports (the build failed on missing beast and multiprecision headers).
Docs: README ServerOptions table for readTimeoutSeconds/bodyLimitBytes;
sample regenerated deterministically.
f8d7a8b to
99775fa
Compare
…rity schemes AllGeneratorsTest requires every registered generator to generate from the canonical 3_0/petstore.yaml, which declares XML/form/multipart payloads and an oauth2 scheme; the previous hard-reject gate broke that contract for the entire project on every CI leg. - preprocessOpenAPI now logs precise warnings for non-JSON request media types, non-JSON response media types, and security scheme types with no runtime credential extractor, while still throwing for the compile-breaking/route-ambiguous categories (parameter styles and shapes, cookie containers, non-scalar array items, non-deepObject object params, heterogeneous enums, ambiguous routes, ranged codes) - the assembler filters declared request media types down to JSON: mixed bodies accept JSON and answer 415 to the rest, JSON-less bodies drop the typed body field entirely (hasBody=false, compiles clean) - unsupported scheme types remain in the route table as declared; the runtime's structurallySatisfied() denies those requests with 401 instead of the generation failing - five rejection tests rewritten as degrade tests asserting the exact generated contracts, plus a canonical-petstore regression test - verified: AllGeneratorsTest 855/855, beast suites 183 green, both samples regenerate with zero diff
The feature set advertised FormUnencoded/FormMultipart support while the server never parses those payloads (they degrade to no typed body). Exclude both parameter features and regenerate the generator docs page.
… variant bodies Move the 16 chunked OAS 3.1 schema-IR templates from the client-only embedded dir into cpp-boost-beast-common so the server generator (whose own dir never carried them) can reach the chunked IR path for large specs, and pin resolution from both generators with a locator test. Wipe the inherited DefaultCodegen typeMapping before seeding it, same as the client generator: AnyType -> oas_any_type_not_mapped is a placeholder header this family never provides, and the OpenAI corpus (FunctionToolParam output_schema anyOf) reaches it through a freeform branch that must resolve to boost::json::value. Render std::variant, std::optional, and std::monostate bodies in BodyJson.h: composition-typed responses serialize the active branch via std::visit, and null branches serialize as JSON null instead of failing to compile.
…d-body JSON members Parameter shapes the JSON runtime cannot decode (content-style, form fields, object/array queries outside deepObject/scalar rules, cookie containers, heterogeneous enums, enum-class dataTypes) now degrade to a dropped handler field with a warning instead of rejecting the document, mirroring the media-type policy so real-world corpora generate code. The OpenAI spec drove the rules: the classifier keys off the resolved dataType the templates emit, so parseScalar can never see a type without an overload. Request-body recovery: a multipart+JSON body whose JSON member $refs a generated model now types the handler body exactly (the model's include is appended via toModelImport when DefaultCodegen did not import it); models aliased to std::variant degrade to no typed body because fromJsonLeaf cannot decode unions; a body model colliding with the generated request struct is namespace-qualified. The model using-directive flag accounts for recovered bodies. The gate now rejects only non-deterministic routing (ambiguous templates, ranged codes). Tests: six degrade rewrites plus four new contracts.
…e the right logger BodyJson.h declares a std::optional overload but relied on <variant> transitively providing <optional>; include it directly. The shared model codegen hardcoded its logger to CppBoostBeastClientCodegen, so server degrade warnings were attributed to the client class; use getClass(). Regenerated petstore server sample picks up the new include.
… rule ArchUnitRulesTest requires slf4j Logger fields to be non-public, non-static and final (PR OpenAPITools#8799); the new assembler logger was static. Both call sites are instance methods, so the field becomes an instance logger.
…tests - Router: tokenize embedded path expressions in one segment; shape keys keep literal text distinct from placeholders - RequestContext held via shared_ptr through the handler/service chain - Optional request bodies no longer fail presence checks when absent - Multi-tag operations get per-operation contract type names - ParamCodecs: float narrowing range checks, exclusive numeric bounds, collection/item constraints (new param-container-constraints include), strict label/matrix percent-encoded codecs, exact integer comparisons - Problem JSON: sanitize malformed UTF-8 in error details - Gate: wildcard response media no longer accepted as JSON; request-body schema selected per declared media; form-encoding hard-reject moved to a server-side override so the shared model path no longer rejects the client corpus; MultiServer feature claim set to false - Generated CMake: warnings are errors by default (opt-out flag added) - README quick-start renders real operations and attach sequence - Runtime regression spec/driver extended to cover all of the above
… regression The sample workflow ran the runtime test with -pl modules/openapi-generator alone, so the 7.26.0-SNAPSHOT sibling (openapi-generator-core) could not be resolved from the snapshot repo on a clean runner checkout. Build the upstream modules with -am and tolerate modules without the selected test.
…l-closed codecs, review gaps - BodyJson: unwrap tagged CompositionBranchValue branches so oneOf responses whose C++ types collide serialize through std::visit - ParamCodecs: reject hex floats explicitly, accept ERANGE underflow, drop the dead errno store; document the whole-input match - param-constraints / param-container-constraints: guard std::regex construction so an out-of-subset pattern fails closed with 400 instead of retry-throwing 500 per request (absent/empty skip it) - Assembler: apiNamespace is constructor-injected (the operations-map merge runs after postProcessOperationsWithModels, which made the collision guard inert); mixed bodies type the JSON member model even when an unparseable member came first; README facts carry model-namespace-qualified send types - Codegen: exclude Host/BasePath global features (never mounted); the server overrides the shared form-encoding reject because it degrades flattened form fields with a warning instead of aborting - Workflow: trigger the sample CI on generator, template, and test resource changes; add generation/runtime coverage for the new paths
Deterministic re-run of bin/generate-samples.sh and bin/utils/export_generator.sh after the fix commit: README quick-start qualifies model response types, BodyJson.h gains the tagged-branch serializer, ParamCodecs.h gains the hex-float gate, and the feature table now reports Host/BasePath as unsupported.
There was a problem hiding this comment.
All reported issues were addressed across 104 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
…mplates - route-ambiguity witness probe + adjacent-expression rejection in the server support-surface gate - pre-escaped literals (path, operationId, baseName, security fields) rendered with triple-brace interpolation only - license header sanitizes '*/' and NUL from info fields - required-null rejection, decode-time reset of every member, nullptr leaf assignment, integral-double integer bodies - two-stage read with interim 100 Continue, 413 version mirroring, 404 query stripping, factory-only HttpServer with null-router guard - JSON numeric wire grammar + locale-independent codecs, cookie quoted-string stripping, UTF-8 code-point lengths, unanchored regex_search with fail-closed grammar gate (Unicode property escapes refused explicitly, never approximated) - enum-always-invalid and present-guarded container constraints, path-item parameter lookup, nullable-body std::optional support, variant key normalization, schema-IR body validation before decode - CI triggers cover the shared model pipeline and common templates
- server runtime driver: unicode property-escape fail-closed legs, 100-continue, oversized-body version mirror, 404 query stripping, PORT/HttpServer ownership probes already covered - exact-number driver: validator-level property-escape refusal incl. doubled-backslash literal case - preserve-additional-properties driver owns its serialized value (the old code bound a reference into a destroyed temporary) - CI triggers widened to shared model-pipeline sources
Regenerated after the review-round template fixes: fail-closed validator (property escapes), decode resets, required-null rejection, HTTP two-stage read + interim 100, codecs with JSON wire grammar, sample README policy notes.
There was a problem hiding this comment.
All reported issues were addressed across 45 files (changes from recent commits).
Requires human review: Auto-approval blocked because this review re-detected 1 unresolved issue already reported by Cubic.
Re-trigger cubic
The cross-layout overlap probe's glob merge consumed the other side's
literals without emitting them (and never emitted while one side's
wildcard ran to the end), so /a/{x}b vs /a/a{y} produced no candidate
witness and the equal-ranking collision slipped the gate. Every
transition now either advances strictly or appends the absorbed byte;
a step budget bounds the search, keeping the probe proof-only (it can
under-report, never falsely reject). Regression-pinned by
rejectsCrossLayoutRouteOverlapWithWitness.
- witness overlap + adjacent-expression codegen rejections - license-header terminator sanitization - nullable model body kept typed as std::optional - HTML-significant route names rendered unescaped - runtime: body enum/required-null 400 legs (validation-leg gated), 404 query-strip, stepwise Expect: 100-continue interim proof, path-item inherited parameter constraint legs
http::message::contains() only exists since Boost 1.85; the Linux CI image ships an older Beast and the sample build failed on it. count() has been available since the first Beast release.
There was a problem hiding this comment.
All reported issues were addressed across 7 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
- parse Expect as a token list: interim 100 only when every expectation is supported, 417 (RFC 9110 10.1.1) otherwise, so no client waits out the read timeout for an interim response that never comes - rewrite parseFloatScalar with a bounded significand and stepped exponent scaling: 0e400 stays zero (no 0 * inf), 1e400 saturates to infinity and dies at the finiteness gate, long finite decimals no longer overflow the accumulator; underflow still rounds toward zero - count UTF-8 code points by validating whole sequences: a malformed byte is never skipped as a continuation, so percent-decoded garbage cannot slip past maxLength - reject integral-double int64 leaves outside 2^53 instead of trusting a possibly-rounded double; keep <limits>/<optional> as direct includes - fail closed for bool/number parameters whose enum has zero representable members; reset inherited explicit defaults through ModelPropertyStorage.value - accept any recursively decodable inner type for an optional request body - document the parameter-vs-body pattern grammar split and the rationale for the whole-payload numeric representability gate; exercise Pet.note, Expect tokens, and the UTF-8 policy in the loopback regression
There was a problem hiding this comment.
All reported issues were addressed across 14 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
…exeme tryGetMathematicalInteger trusted any integral double inside the destination range, but above 2^53 the double is the image of a 2-or- wider rounding band and every cast-based exactness check agrees with the band's centre: 9007199254740993.0 arrived as ...92 through value_to<int64_t>, through the model pipeline, and through the server's int64 body leaf alike. - Oas31ExactJson.h gains exactNumericLexeme + exactLexemeToInteger: inside a live ExactInstanceScope the decimal text is authoritative and converts exactly, range-checked against the destination. - tryGetMathematicalInteger keeps integral doubles only while |value| <= 2^53; past that window it recovers from the lexeme or refuses (fail closed, 400, never a corrupted int64). - JsonValueConverter<std::int64_t> specialisation replaces boost's value_to path, which never consulted the lexeme. - BodyJson.h's int64 leaf now delegates to the shared helper, one judgment for model, body, and validator paths. - Client and server samples regenerated; exact-runtime boundary expectations updated to the new (stricter) contract with paired no-lexeme-refusal / in-scope-exact legs.
…ed trie
The ambiguous-route gate enumerated candidate witnesses with a
step-budgeted depth-first glob merge. Branchy-but-intersecting pairs
(alternating wildcard/literal layouts like /v/{p}a{p}a{p}a vs
/v/a{p}a{p}a{p}) exhaust the step cap without emitting a witness, so a
real collision could be silently under-reported and shipped as a
runtime-shadowed route.
Replace it with product-NFA trie BFS over (i,j) token positions:
epsilon-closure per level, emitted chars advance at least one side, so
a shortest witness has length at most n+m. Finishing all levels is a
disjointness proof, not a timeout. Regression test drives the old
under-report through to a rejection naming the witness path.
…ct lists, double gates Four wire-level correctness gaps from the third review round, each with a loopback driver leg: - UTF-8 length checks (maxLength/minLength) now validate sequence structure, not just lead bytes: overlong encodings, surrogates, and out-of-range tails degrade to a strict byte count and cannot be smuggled through as one code point (param codecs and the body validator share the grammar). - The body validator's std::wregex path encodes scalars above U+FFFF as UTF-16 surrogate pairs on 16-bit wchar_t (Windows); storing the bare code point truncated it silently. README documents the platform split. - Expect handling tokenises EVERY repeated Expect field line per RFC 9110 5.3, not just the first: an unsupported token on line two answers 417 instead of being ignored. - parseFloatScalar gates against the DESTINATION range for float and double alike. Where long double is wider than double (x86 80-bit), 1e400 parses finite and the old double-only gate handed the service an infinity cast out of the schema's range; both platforms now answer 400 identically. Samples regenerated.
There was a problem hiding this comment.
All reported issues were addressed across 33 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
Router::splitPath strips the query string at registration, so '/responses?beta=true' registers the very route '/responses' — a literal duplicate the shape gate should name as such. The key was computed over the raw template, letting every beta-path pair slip to the witness probe and get mislabelled as registration-order ambiguity with a fabricated witness. The OpenAI document's '/x?beta=true' idiom now produces the honest 'have the same shape' diagnostic; regression test added.
…e image - Inside an ExactInstanceScope the original token outranks its binary image unconditionally: an image check accepts 1.0000000000000001 (rounds to 1.0) and refuses 9223372036854775807.0 (rounds past int64's max), inverting both verdicts. - The 2^53 trust window is open on both signed edges: -2^53 is also the ties-to-even image of -9007199254740993, so the negative boundary image was decoded as a different wire integer than the positive one already was. Zero stays accepted for unsigned destinations (no token shares its image). - Regenerated both committed samples deterministically.
Two suppression rules in the product-trie witness search could
"prove" two routable templates disjoint when they genuinely
collide:
- the level-0 accept (both segments matching an empty path
segment) was filtered out, so pairs colliding only through
empty captures went unreported;
- every step where BOTH sides merely absorb a char was skipped,
but a whole-segment capture may not be empty (Router::matches
refuses it) and absorbs only at index 0, so '/{p}' vs '{q}'
needed exactly one root both-absorb char to yield a witness.
Allow exactly one both-absorb step from the root state at level 0
(complete: whole-segment captures only need one stretched char,
partial captures may be empty), keep empty candidates in the list,
and let the caller's whole-path Router::matches mirror reject
unverifiable ones. New regression: '/{p}/a/b' vs '/{q}/a{r}/b'
collide on /c/a/b and must be refused; the old search generated
them.
The repeated-100-continue probe broke out of its read loop as soon as the 200 status line appeared in the transcript. The body can split across socket segments (headers and partial body in one read, the tail in the next), so the 'twice' assertion raced the body and the probe was flaky under load. Stop only once both the status line AND the body marker arrived; EOF (Connection: close) still ends the read as before.
There was a problem hiding this comment.
All reported issues were addressed across 6 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
…budget The both-absorb root step is only reachable when both flattened segments can absorb a char at index 0 (a wildcard each). Allocate the extra level only then, and pin the 4M cell guard to the pre-root-absorb product so a pair that was searchable before the level existed (e.g. two 125-char literal-initial segments: 126x126x251 = 3,984,876 base vs 4,000,752 with the level) stays searchable instead of under-reporting its collision. Regression test proves the near-budget collision is still reported.
Inside the doubles' exact window every image names exactly one integer, so a signed destination whose full range fits within it (int32 and narrower) must accept its own minimum -2^digits; the open lower edge is only sound for destinations reaching the precision boundary (int64), whose -2^53 image is ambiguous with -9007199254740993. Keep the upper edge open everywhere. Native regression covers int32 min/max acceptance and the int64 -2^53 refusal.
There was a problem hiding this comment.
All reported issues were addressed across 6 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
Each template forces at least 124 literal 'l' chars into the colliding segment (captures may be empty), so 124 is the shortest joint match. Asserting the full 'both match' diagnostic rules out passing on a shorter prefix inside a wrong-length witness.
The previous wording implied -2^53 itself is accepted for a narrower signed destination; the destination-bounds check rejects it as out-of-range. What is accepted is the destination's own minimum, whose image is unambiguous inside the exact window. Regenerated both samples.
cpp-boost-beast-server: new OpenAPI HTTP/1.1 server generator (C++17)
Adds a new
cpp-boost-beast-servergenerator that produces a C++17 Boost.Beast HTTP/1.1 server from OpenAPI documents (OAS 3.0 and 3.1). It shares the model pipeline with the client generator (refactored intoCppBoostBeastModelCodegen) and reuses the OAS 3.1 schema-validation runtime for request-body validation.Scope
Generator
cpp-boost-beast-servergenerator (beta) with typed request/responder contracts per operation (GetPetByIdRequest,GetPetByIdResponder), OAS parameter deserialization (path/query/header/cookie, incl.simple/label/matrix/form/spaceDelimited/pipeDelimited/deepObject-string-map styles), and a security seam (Authorizer, deny-by-default).CppBoostBeastModelCodegen; the shared decode contract is documented below (integers above 2^53 now decode from the exact wire lexeme on both generators)./a/{x}/cvs/a/{y}/c), including query-suffixed duplicates:Router::splitPathstrips the query at registration, so/responses?beta=trueIS the route/responsesand is reported as the literal same-shape duplicate it is (the OpenAI document's beta-path idiom);/v/{p1}a{p2}a{p3}avs/v/a{p4}a{p5}a{p6}— which a step-budgeted DFS under-reports — can never ship as runtime-shadowed routes);2XX). Fails closed with precise diagnostics naming a verified witness path.std::variant(composition unions, including models aliased to one) get no typed body, since decode-side union matching needs the schema matcher the request path does not run.$refs a generated model types the handler body exactly (its#includeis appended viatoModelImport); a body model colliding with the generated request struct is namespace-qualified.application/problem+jsonerrors throughout, withWWW-Authenticatechallenges for http-scheme security.Runtime
HttpServerwith keep-alive, request version/keep-alive mirroring, 413 body-limit handling that closes the connection, and atomic single-completion guard on responders./pets/bulkwins over an earlier-registered/pets/{petId}.ExactInstanceScoperecovers the mathematical integer from the wire lexeme (9007199254740993.0decodes exactly — the binary image silently rounds it), and with no lexeme available the decode refuses (400) instead of corrupting.value_to<std::int64_t>(whose cast-equality check agrees with the rounded image) is replaced by aJsonValueConverter<std::int64_t>specialisation on both generators.maxLength/minLength, parameter and body surfaces) validate sequence structure, not just lead bytes: overlong encodings, surrogates, and out-of-range tails degrade to a strict byte count, so continuation bytes cannot be smuggled through a naive count.std::wregex; the validator stores UTF-16 surrogate pairs on 16-bitwchar_t(Windows) instead of silently truncating scalars above U+FFFF. README documents the platform split (on Windows.matches one UTF-16 code unit).Expecthandling tokenises every repeated field line per RFC 9110 §10.1.1 (unsupported token on line two answers 417, not ignored).1e400answers 400 identically on platforms wherelong doubleis wider thandouble(x86 80-bit) instead of handing the service an infinity.security: []or an empty OR-group) bypass the authorization gate with no authorizer required.-Wall.Sample, docs, CI
samples/server/petstore/cpp-boost-beast-server(byte-deterministic regeneration).docs/generators/cpp-boost-beast-server.mdand generator index entry..github/workflows/samples-cpp-boost-beast-server.yaml: Ubuntu / macOS / Windows build matrix with per-OS Boost installs (Windows: vcpkgboost-asio/boost-beast/boost-json/boost-url/boost-multiprecision).Verification
498c71d, ~1.3 MB, 1,608 model files, 23 API files) generates, compiles with-Wall -Wextraat 0 errors / 0 warnings, and links — exercising the degrade policy (form fields, variant-alias and mixed bodies, enum-class params) and the recovery path (recovered JSON-member bodies with appended includes) at scale. On the current spec head the generator hard-rejects, correctly:GET /videos/characters/contentis matched by both/videos/characters/{character_id}and/videos/{video_id}/contentwith equal ranking, and the beta paths (/responses?beta=true) register as literal duplicates of/responses— neither routes deterministically, and the diagnostics name both classes precisely.AllGeneratorsTestpasses (855 cases), i.e. this generator acceptssrc/test/resources/3_0/petstore.yaml(the spec that mixes XML/form/multipart payloads and an oauth2 scheme) exactly as the harness requires — degrade, not reject.cppboostbeast(250) +cppboostbeastserver(40) packages, 0 failures, 0 skips — the native generated-C++ runtime suites executed for real here (Boost headers present); they skip on runners without them. Includes the loopback runtime driver's new legs: exact-lexeme int64 above 2^53, repeated-Expect417, CJK/overlong UTF-8 header counts,1e400double 400, and the branchy route-collision witness.JsonValueConverter<std::int64_t>specialisation in the generated models +ValidationTypes.h) and the stricter UTF-8 code-point count inOas31Validator.h; server and client samples are regenerated together.Notes